<?php
/**
 * Created by PhpStorm.
 * User: zws
 * Date: 2018/9/8
 * Time: 11:02
 * 检测人员管理
 */
namespace app\index\service;

use app\common\model\MachineLogModel;
use app\common\model\MachineModel;
use app\common\model\ModuleLogModel;
use app\common\model\ModuleModel;
use app\common\model\OperateModel;
use think\Exception;
use think\Db;
class MachineService
{
    protected static $machineModel;
    protected static $moduleModel;
    protected static $operateModel;
    protected static $machineLogModel;
    protected static $moduleLogModel;

    /**
     * MachineService constructor.
     * @param MachineModel $machineModel
     * @param OperateModel $operateModel
     * @param ModuleModel $moduleModel
     * @param MachineLogModel $machineLogModel
     * @param ModuleLogModel $moduleLogModel
     */
    public function __construct(MachineModel $machineModel,
                                OperateModel $operateModel,
                                ModuleModel $moduleModel,
                                MachineLogModel $machineLogModel,
                                ModuleLogModel $moduleLogModel)
    {
        self::$machineModel = $machineModel;
        self::$operateModel = $operateModel;
        self::$moduleModel = $moduleModel;
        self::$machineLogModel = $machineLogModel;
        self::$moduleLogModel = $moduleLogModel;
    }

    /**
     * zws
     * 获取测试仪列表
     * @param $request
     * @return array
     */
    public function machine_list($request)
    {
        if(empty($request->page))
        {
            $request->page = 1;
        }
        if(empty($request->limit))
        {
            $request->limit = 20;
        }
        $type = $request->role;
        $where = "";
        if($type == 2)
        {
            $where1 = [
                ['user_id', '=', $request->tokenId],
                ['machine_code', '<>', 'null'],
            ];
            if($request->page > 0) {
                $machine_code_arr = self::$operateModel->where($where1)
                    ->distinct(true)
                    ->field('machine_code')
                    ->page($request->page, $request->limit)
                    ->column('machine_code');
            }else{
                $machine_code_arr = self::$operateModel->where($where1)
                    ->distinct(true)
                    ->field('machine_code')
                    ->column('machine_code');
            }
            $machine_code_str = "'".implode("','", $machine_code_arr)."'";
            $where = " machine_code in ($machine_code_str) or user_id = ".$request->tokenId;
        }

        $count = self::$machineModel->where($where)
            ->count();
        if ($count < 1) {
            return ['links' => [], 'count' => $count];
        }
        if($request->page > 0)
        {
            $result = self::$machineModel->where($where)
                ->page($request->page, $request->limit)
                ->order('create_time', 'desc')
                ->select();
        }else
        {
            $result = self::$machineModel->where($where)
                ->order('create_time', 'desc')
                ->select();
        }
        if($result)
        {
            $machine_codes = [];
            foreach ($result as $v)
            {
                $machine_codes[] = $v['machine_code'];
            }
            $last_machine_datas = $this->get_last_machine($machine_codes);
            if($type == 1)
            {
                $module_datas = $this->get_module($machine_codes);
            }
            foreach ($result as $k=>$v)
            {
                $last_machine_data = isset($last_machine_datas[$v['machine_code']]) ?
                    $last_machine_datas[$v['machine_code']] : $v;
                $result[$k]->start_date = $v['create_time'] ? date('Y-m-d H:i:s', $v['create_time']) : '';
                $result[$k]->end_date = $last_machine_data['create_time'] ? date('Y-m-d H:i:s', $last_machine_data['create_time']) : '';
                $result[$k]->machine_limit = 0;
                $result[$k]->machine_detail = $last_machine_data['machine_detail'];
                if($last_machine_data['remark'])
                {
                    $result[$k]->remark = $last_machine_data['remark'];
                }
                if($type == 1)
                {
                    $result[$k]->machine_limit = 1;
                }
                $result[$k]['modules'] = ($type == 1 && isset($module_datas[$v['machine_code']])) ? $module_datas[$v['machine_code']] :
                    [];
            }

        }
        return ['links' => $result, 'count' => $count];
    }

    /**
     * zws
     * 获取最新校准测试仪
     * @param $machine_codes
     * @return array
     */
    public function get_last_machine($machine_codes)
    {
        $where = ' 1=1';
        if($machine_codes)
        {
            if(is_array($machine_codes))
            {
                $machine_codes_str = "'".implode("','", $machine_codes)."'";
                $where .= " and machine_code in ($machine_codes_str)";
            }else{
                $where .= " and machine_code = $machine_codes";
            }
        }
        $sql = "select a.* from (select * from machine_log where $where order by id desc) a GROUP BY a
.machine_code";
        $data = [];
        $result = self::$machineLogModel->query($sql);
        if($result)
        {
            foreach ($result as $v)
            {
                $data[$v['machine_code']] = $v;
            }
        }
        return $data;
    }

    /**
     * zws
     *获取仪器下面的模块
     * @param $machine_codes
     * @return array
     */
    public function get_module($machine_codes)
    {
        if(empty($machine_codes))
        {
            return [];
        }
        if(is_array($machine_codes))
        {
            $where1[] = ['machine_code', 'in', $machine_codes];
        }else{
            $where1 = ['machine_code'=>$machine_codes];
        }
        $module_datas = self::$moduleModel->where($where1)->select();
        if(!$module_datas)
        {
            return [];
        }
        $module_data_arr = [];
        $module_codes = [];
        foreach ($module_datas as $v)
        {
            $module_codes[] = $v['module_code'];
        }
        $last_module_datas = $this->get_last_module($module_codes);
        foreach ($module_datas as $v)
        {
            if(isset($last_module_datas[$v['module_code']]))
            {
                $last_module_datas[$v['module_code']]['date'] = $last_module_datas[$v['module_code']]['create_time'] ?
                    date("Y-m-d H:i:s", $last_module_datas[$v['module_code']]['create_time']) : '';
                $module_data_arr[$v['machine_code']][] = $last_module_datas[$v['module_code']];
            }
        }

        return $module_data_arr;
    }

    /**
     * zws
     * 根据模块id获取最新模块信息
     * @param $module_codes
     * @return array
     */
    public function get_last_module($module_codes)
    {
        if(empty($module_codes))
        {
            return [];
        }
        $module_codes_str = "'".implode("','", $module_codes)."'";
        $where = " module_code in ($module_codes_str)";
        $sql = "select a.* from (select * from module_log where $where order by id desc) a GROUP BY a
.module_code";
        $data = [];
        $result = self::$moduleLogModel->query($sql);
        if($result)
        {
            foreach ($result as $v)
            {
                $v['module_id'] = $v['module_code'];
                $data[$v['module_code']] = $v;
            }
        }
        return $data;
    }
    /**
     * 获取测试仪信息
     * @param $request
     * @return array|null|\PDOStatement|string|\think\Model
     */
    public function machine_detail($request)
    {
        if(empty($request->machine_code))
        {
            app_fail(8299);
        }
        $machine_data = self::$machineModel->where(['machine_code'=>$request->machine_code])->find();
        if(empty($machine_data))
        {
            app_fail(8298);
        }
        $last_machine_data = $this->get_last_machine($request->machine_code);
        $last_machine_arr = isset($last_machine_data[$request->machine_code]) ?
            $last_machine_data[$request->machine_code] : $machine_data;
        $machine_data->start_date = $machine_data->create_time ? date('Y-m-d H:i:s', $machine_data->create_time) : '';
        $machine_data->end_date = $last_machine_arr['create_time'] ? date('Y-m-d H:i:s',
            $last_machine_arr['create_time']) : '';
        $machine_data->machine_detail = $last_machine_arr['machine_detail'];
        if($last_machine_arr['remark'])
        {
            $machine_data->remark = $last_machine_arr['remark'];
        }
        $machine_data->machine_limit = 0;
        $machine_data->modules = [];
        return $machine_data;
    }

    /**
     * zws
     * 添加测试仪
     * @param $params
     * @return bool
     */
    public function add_machine($params)
    {
        if($params['role'] != 1)
        {
            app_fail(9978);
        }
        if(!isset($params['machine_name']) || !$params['machine_name'])
        {
            app_fail(8299);
        }
        if(isset($params['modules']))
        {
            $params['modules'] = json_decode($params['modules'], true);
        }
        $this->judge_param($params);
        $machine_data = self::$machineModel->where(['machine_code'=>$params['machine_code']])
            ->find();
        if($machine_data)
        {
            app_fail(8287);
        }
        //判断是否有模块存在并且被其他仪器使用
        $module_id_arr = array_column($params['modules'], 'module_id');
        //获取当前未被使用的模块
        $where2 = [
            ['module_code', 'in', $module_id_arr],
        ];
        $model_datas = self::$moduleModel->where($where2)->select();
        $model_code_arr = [];//已存在code,且未关联测试仪
        $module_code_arr = [];//存在的所有code
        foreach ($model_datas as $v)
        {
            $module_code_arr[] = $v['module_code'];
            if($v['machine_code'] && $v['machine_code'] != $params['machine_code'])
            {
                app_fail(8289);
            }
            if(empty($v['machine_code']))
            {
                $model_code_arr[] = $v['module_code'];
            }
        }
        $add_module_code = array_diff($module_id_arr, $module_code_arr);//新增加的模块
        $data = array(
            'machine_code'=>$params['machine_code'],
            'machine_name'=>$params['machine_name'],
            'machine_detail'=>$params['machine_detail'],
            'user_id'=>$params['tokenId'],
            'remark'=>isset($params['remark']) ? $params['remark'] : '',
            'create_time'=>time(),
            'update_time'=>time(),
        );
        Db::startTrans();
        try{
            //测试仪记录
            self::$machineModel->save($data);
            //测试仪器log记录
            self::$machineLogModel->save($data);
            $machine_log_id = self::$machineLogModel->id;
            //已有模块和测试仪关联
            if($model_code_arr)
            {
                self::$moduleModel->where(['module_code', 'in', $model_code_arr])->update(['machine_code'=>$params['machine_code']]);
            }
            $add_module_datas = [];
            $add_module_log_datas = [];
            foreach ($params['modules'] as $v)
            {
                $add_data_arr = [
                    'module_name'=>$v['module_name'],
                    'machine_code'=>$params['machine_code'],
                    'content'=>$v['content'],
                    'module_type'=>$v['module_type'],
                    'module_code'=>$v['module_id'],
                    'user_id'=>$params['tokenId'],
                    'remark'=>isset($v['remark']) ? $v['remark'] : '',
                    'create_time'=>time(),
                    'update_time'=>time(),
                ];
                if(in_array($v['module_id'], $add_module_code))
                {
                    $add_module_datas[] = $add_data_arr;
                }
                $add_data_arr['machine_log_id'] = $machine_log_id;
                $add_module_log_datas[] = $add_data_arr;
            }
            //新模块增加
            self::$moduleModel->insertAll($add_module_datas);
            //模块log增加
            self::$moduleLogModel->insertAll($add_module_log_datas);
            Db::commit();
            return true;
        }catch (Exception $e){
            Db::rollback();
            app_fail(9899);//编辑失败
        }
    }

    /**
     * 判断添加仪器参数
     * zws
     * @param $params
     */
    public function judge_param($params)
    {
        if(empty($params))
        {
            app_fail(9997);
        }
        if(!isset($params['machine_code']) || !$params['machine_code'])
        {
            app_fail(8299);
        }

        if(!isset($params['machine_detail']) || !$params['machine_detail'])
        {
            app_fail(8288);
        }
        if(!isset($params['modules']) || count($params['modules']) <= 0)
        {
            app_fail(8293);
        }
        foreach ($params['modules'] as $v)
        {
            $this->judge_module($v);
        }
    }

    /**
     * zws
     * 添加模块
     * @param $params
     * @return bool
     */
    public function add_module($params)
    {
        if(empty($params))
        {
            app_fail(9997);
        }
        if($params['role'] != 1)
        {
            app_fail(9978);
        }
        $this->judge_module($params);
        $model_data = self::$moduleModel->where(['module_code'=>$params['module_id']])->find();
        if($model_data)
        {
            app_fail(8289);
        }
        $data = array(
            'machine_code'=>isset($params['machine_code']) ? $params['machine_code'] : '',
            'user_id'=>$params['tokenId'],
            'module_name'=>$params['module_name'],
            'content'=>$params['content'],
            'module_type'=>$params['module_type'],
            'module_code'=>$params['module_id'],
            'remark'=>isset($params['remark']) ? $params['remark'] : '',
            'create_time'=>time(),
            'update_time'=>time(),
        );
        Db::startTrans();
        try{
            self::$moduleLogModel->save($data);
            $result = self::$moduleModel->save($data);
            Db::commit();
            return $result ? true : false;
        }catch (Exception $e){
            Db::rollback();
            app_fail(9899);//编辑失败
        }
    }

    /**
     * zws
     * 判断添加模块的参数
     * @param $params
     */
    public function judge_module($params)
    {

        if(!isset($params['module_name']) || !$params['module_name'])
        {
            app_fail(8293);
        }
        if(!isset($params['content']) || !$params['content'])
        {
            app_fail(8292);
        }
        if(!isset($params['module_type']) || !$params['module_type'])
        {
            app_fail(8291);
        }
        if(!isset($params['module_id']) || !$params['module_id'])
        {
            app_fail(8291);
        }

        if(isset($params['machine_code']) && $params['machine_code'])
        {
            $machine_data = self::$machineModel->where(['machine_code'=>$params['machine_code']])
                ->find();
            if(!$machine_data)
            {
                app_fail(8298);
            }
        }
    }

    /**
     * zws
     * 校准测试仪器
     * @param $params
     * @return bool
     */
    public function calibration_machine($params)
    {
        if(isset($params['modules']))
        {
            $params['modules'] = json_decode($params['modules'], true);
        }
        $this->judge_param($params);
        $machine_data = self::$machineModel->where(['machine_code'=>$params['machine_code']])
            ->find();
        if(!$machine_data)
        {
            //测试仪器不存在
            app_fail(8298);
        }
        //判断是否有模块存在并且被其他仪器使用
        $module_id_arr = array_column($params['modules'], 'module_id');
        //获取当前未被使用的模块
        $where2 = [
            ['module_code', 'in', $module_id_arr],
        ];
        $model_datas = self::$moduleModel->where($where2)->select();
        $model_code_arr = [];//已存在code,且未关联测试仪
        $module_code_arr = [];//存在的所有code
        foreach ($model_datas as $v)
        {
            $module_code_arr[] = $v['module_code'];
            if($v['machine_code'] && $v['machine_code'] != $params['machine_code'])
            {
                app_fail(8289);
            }
            if(empty($v['machine_code']))
            {
                $model_code_arr[] = $v['module_code'];
            }
        }
        $add_module_code = array_diff($module_id_arr, $module_code_arr);//新增加的模块
        $data = array(
            'machine_code'=>$params['machine_code'],
            'machine_name'=>$machine_data['machine_name'],
            'machine_detail'=>$params['machine_detail'],
            'user_id'=>$params['tokenId'],
            'remark'=>isset($params['remark']) ? $params['remark'] : '',
            'create_time'=>time(),
            'update_time'=>time(),
        );
        Db::startTrans();
        try{
            //添加操作记录
            $operate_data = self::$operateModel->where(['machine_code'=>$params['machine_code'],
                'user_id'=>$params['tokenId']])->find();
            if(!$operate_data)
            {
                $add_operate_data = [
                    'res_code' => $params['machine_code'],
                    'user_id' => $params['tokenId'],
                    'create_time' => time(),
                    'update_time' => time(),
                ];
                self::$operateModel->save($add_operate_data);
            }
            //测试仪器log记录
            self::$machineLogModel->save($data);
            $machine_log_id = self::$machineLogModel->id;
            //已有模块和测试仪关联
            if($model_code_arr)
            {
                self::$moduleModel->where(['module_code', 'in', $model_code_arr])->update(['machine_code'=>$params['machine_code']]);
            }
            $add_module_datas = [];
            $add_module_log_datas = [];
            foreach ($params['modules'] as $v)
            {
                $add_data_arr = [
                    'module_name'=>$v['module_name'],
                    'machine_code'=>$params['machine_code'],
                    'content'=>$v['content'],
                    'module_type'=>$v['module_type'],
                    'module_code'=>$v['module_id'],
                    'user_id'=>$params['tokenId'],
                    'remark'=>isset($v['remark']) ? $v['remark'] : '',
                    'create_time'=>time(),
                    'update_time'=>time(),
                ];
                if(in_array($v['module_id'], $add_module_code))
                {
                    $add_module_datas[] = $add_data_arr;
                }
                $add_data_arr['machine_log_id'] = $machine_log_id;
                $add_module_log_datas[] = $add_data_arr;
            }
            //新模块增加
            self::$moduleModel->insertAll($add_module_datas);
            //模块log增加
            self::$moduleLogModel->insertAll($add_module_log_datas);
            Db::commit();
            return true;
        }catch (Exception $e){
            Db::rollback();
            app_fail(9899);//编辑失败
        }
    }


}